<template>
    <div id="login-modal" class="modal fade" tabindex="-1" role="dialog">
        <div class="modal-dialog modal-login" role="document">
            <div class="modal-content">
                <div class="modal-body">

                    <div class="login-div" v-show="MODAL_STATUS === STATUS_LOGIN">
                        <h3>登录</h3>
                        <div class="form-group">
                            <input v-model="member.mobile" class="form-control" placeholder="手机号">
                        </div>
                        <div class="form-group">
                            <input v-model="member.password" class="form-control" type="password" placeholder="密码">
                        </div>
                        <div class="form-group">
                            <div class="input-group">
                                <input id="image-code-input" class="form-control" type="text" placeholder="验证码"
                                       v-model="member.imageCode">
                                <div class="input-group-addon" id="image-code-addon">
                                    <img id="image-code" alt="验证码" v-on:click="loadImageCode()"/>
                                </div>
                            </div>
                        </div>
                        <div class="form-group">
                            <button v-on:click="loginMember()" class="btn btn-primary btn-block submit-button">
                                登录
                            </button>
                        </div>
                        <div class="form-group">
                            <div class="checkbox">
                                <label>
                                    <input type="checkbox" class="rememberMe" v-model="rememberMe">
                                    记住密码
                                </label>
                                <div class="pull-right">
                                    <a href="javascript:;" v-on:click="toForgetDiv()">忘记密码</a>&nbsp;
                                    <a href="javascript:;" v-on:click="toRegisterDiv()">我要注册</a>
                                </div>
                            </div>
                        </div>
                        <div class="form-group to-register-div">
                        </div>
                    </div>

                    <div class="register-div" v-show="MODAL_STATUS === STATUS_REGISTER">
                        <h3>注&nbsp;&nbsp;册</h3>
                        <div class="form-group">
                            <input id="register-mobile"
                                   v-model="memberRegister.mobile"
                                   v-on:blur="onRegisterMobileBlur()"
                                   v-bind:class="registerMobileValidateClass"
                                   class="form-control" placeholder="手机号码">
                            <span v-show="registerMobileValidate === false" class="text-danger">
                                手机号11位数字，且必须未注册
                            </span>
                        </div>
                        <div class="form-group">
                            <div class="input-group">
                                <input id="register-mobile-code"
                                       class="form-control"
                                       placeholder="手机验证码"
                                       v-on:blur="onRegisterMobileCodeBlur()"
                                       v-bind:class="registerMobileCodeValidateClass"
                                       v-model="memberRegister.code">
                                <div class="input-group-append">
                                    <button class="btn btn-outline-secondary" id="register-send-code-btn"
                                            v-on:click="sendSmsForRegister()">发送验证码
                                    </button>
                                </div>
                            </div>
                            <span v-show="registerMobileCodeValidate === false" class="text-danger">
                                请输入6位短信验证码
                            </span>
                        </div>
                        <div class="form-group">
                            <input id="register-name"
                                   v-on:blur="onRegisterNameBlur()"
                                   v-bind:class="registerNameValidateClass"
                                   v-model="memberRegister.name"
                                   class="form-control" placeholder="昵称">
                            <span v-show="registerNameValidate === false" class="text-danger">
                                昵称2到20位中文，字母，数字，下划线组合
                            </span>
                        </div>
                        <div class="form-group">
                            <input id="register-password"
                                   v-on:blur="onRegisterPasswordBlur()"
                                   v-bind:class="registerPasswordValidateClass"
                                   v-model="memberRegister.passwordOriginal"
                                   class="form-control" placeholder="密码" type="password">
                            <span v-show="registerPasswordValidate === false" class="text-danger">
                                密码最少6位，至少包含字母和数字
                            </span>
                        </div>
                        <div class="form-group">
                            <input id="register-confirm-password"
                                   v-on:blur="onRegisterConfirmPasswordBlur()"
                                   v-bind:class="registerConfirmPasswordValidateClass"
                                   v-model="memberRegister.confirm"
                                   class="form-control" placeholder="确认密码"
                                   name="memberRegisterConfirm" type="password">
                            <span v-show="registerConfirmPasswordValidate === false" class="text-danger">
                                密码不一致
                            </span>
                        </div>
                        <div class="form-group">
                            <button class="btn btn-primary btn-block submit-button" v-on:click="register()">
                                注&nbsp;&nbsp;册
                            </button>
                        </div>
                        <div class="form-group to-login-div">
                            <a href="javascript:;" v-on:click="toLoginDiv()">我要登录</a>
                        </div>
                    </div>

                    <div class="forget-div" v-show="MODAL_STATUS === STATUS_FORGET">
                        <h3>忘记密码</h3>
                        <div class="form-group">
                            <input id="forget-mobile"
                                   v-model="memberForget.mobile"
                                   v-on:blur="onForgetMobileBlur()"
                                   v-bind:class="forgetMobileValidateClass"
                                   class="form-control" placeholder="手机号">
                            <span v-show="forgetMobileValidate === false" class="text-danger">
                                手机号11位数字，且必须已注册
                            </span>
                        </div>
                        <div class="form-group">
                            <div class="input-group">
                                <input id="forget-mobile-code"
                                       class="form-control"
                                       placeholder="手机验证码"
                                       v-on:blur="onForgetMobileCodeBlur()"
                                       v-bind:class="forgetMobileCodeValidateClass"
                                       v-model="memberForget.code">
                                <div class="input-group-append">
                                    <button v-on:click="sendSmsForForget()" class="btn btn-outline-secondary" id="forget-send-code-btn">
                                        发送验证码
                                    </button>
                                </div>
                            </div>
                            <span v-show="forgetMobileCodeValidate === false" class="text-danger">
                                请输入短信6位验证码
                            </span>
                        </div>
                        <div class="form-group">
                            <input id="forget-password"
                                   v-on:blur="onForgetPasswordBlur()"
                                   v-bind:class="forgetPasswordValidateClass"
                                   v-model="memberForget.passwordOriginal"
                                   class="form-control" placeholder="密码" type="password">
                            <span v-show="forgetPasswordValidate === false" class="text-danger">
                                密码最少6位，包含字母和数字
                            </span>
                        </div>
                        <div class="form-group">
                            <input id="forget-confirm-password"
                                   v-on:blur="onForgetConfirmPasswordBlur()"
                                   v-bind:class="forgetConfirmPasswordValidateClass"
                                   v-model="memberForget.confirm"
                                   class="form-control" placeholder="确认密码" type="password">
                            <span v-show="forgetConfirmPasswordValidate === false" class="text-danger">
                                密码不一致
                            </span>
                        </div>
                        <div class="form-group">
                            <button v-on:click="resetPassword()" class="btn btn-primary btn-block submit-button">
                                重&nbsp;&nbsp;置
                            </button>
                        </div>
                        <div class="form-group to-login-div">
                            <a href="javascript:;" v-on:click="toLoginDiv()">我要登录</a>
                        </div>
                    </div>

                </div>
            </div><!-- /.modal-content -->
        </div><!-- /.modal-dialog -->
    </div><!-- /.modal -->
</template>

<script>
    import Album_Md5 from '../../public/static/js/album_member_md5'
    export default {
        components: {Album_Md5},
        name: 'theLogin',
        data: function () {
            return {
                // 模态框内容切换：登录、注册、忘记密码
                STATUS_LOGIN: "STATUS_LOGIN",
                STATUS_REGISTER: "STATUS_REGISTER",
                STATUS_FORGET: "STATUS_FORGET",
                MODAL_STATUS: "",

                member: {},
                memberForget: {},

                memberRegister: {},
                rememberMe: true, // 记住密码
                imageCodeToken: "",

                // 注册框显示错误信息
                registerMobileValidate: null,
                registerMobileCodeValidate: null,
                registerPasswordValidate: null,
                registerNameValidate: null,
                registerConfirmPasswordValidate: null,

                // 忘记密码框显示错误信息
                forgetMobileValidate: null,
                forgetMobileCodeValidate: null,
                forgetPasswordValidate: null,
                forgetConfirmPasswordValidate: null,
            }
        },

        computed: {
            //computed监听数据变化，当方法中表达式为true时，返回左边的字符串
            registerMobileValidateClass: function () {
                return {
                    'border-success': this.registerMobileValidate === true,
                    'border-danger': this.registerMobileValidate === false,
                }
            },
            registerMobileCodeValidateClass: function () {
                return {
                    'border-success': this.registerMobileCodeValidate === true,
                    'border-danger': this.registerMobileCodeValidate === false,
                }
            },
            registerPasswordValidateClass: function () {
                return {
                    'border-success': this.registerPasswordValidate === true,
                    'border-danger': this.registerPasswordValidate === false,
                }
            },
            registerNameValidateClass: function () {
                return {
                    'border-success': this.registerNameValidate === true,
                    'border-danger': this.registerNameValidate === false,
                }
            },
            registerConfirmPasswordValidateClass: function () {
                return {
                    'border-success': this.registerConfirmPasswordValidate === true,
                    'border-danger': this.registerConfirmPasswordValidate === false,
                }
            },
            forgetMobileValidateClass: function () {
                return {
                    'border-success': this.forgetMobileValidate === true,
                    'border-danger': this.forgetMobileValidate === false,
                }
            },
            forgetMobileCodeValidateClass: function () {
                return {
                    'border-success': this.forgetMobileCodeValidate === true,
                    'border-danger': this.forgetMobileCodeValidate === false,
                }
            },
            forgetPasswordValidateClass: function () {
                return {
                    'border-success': this.forgetPasswordValidate === true,
                    'border-danger': this.forgetPasswordValidate === false,
                }
            },
            forgetConfirmPasswordValidateClass: function () {
                return {
                    'border-success': this.forgetConfirmPasswordValidate === true,
                    'border-danger': this.forgetConfirmPasswordValidate === false,
                }
            },
        },

        mounted() {
            let _this = this;
            _this.rememberMember();//页面初始化时执行记住我函数
            console.log(SALT.SALT_PREFIX);
            console.log(SALT.SALT_SUFFIX);
            // vue事件总线执行端，让两个毫不相干的组件或vue页面关联起来。
            // $on方法的第一个是事件名称(由触发端自定义)，通过事件名称关联触发端并执行事件内容。
            // 第二个是function函数，它能给事件传递参数
            _this.$event.$on("openLoginModal", function (param) {
                // debugger;
                // console.log("param = ",param);
                _this.openLoginModal();
            });
        },
        methods: {

            //-------------------------------- 忘记密码框校验 ----------------------------

            onForgetMobileBlur () {
                let _this = this;
                return _this.forgetMobileValidate = Pattern.validateMobile(_this.memberForget.mobile);
            },

            onForgetMobileCodeBlur () {
                let _this = this;
                return _this.forgetMobileCodeValidate = Pattern.validateMobileCode(_this.memberForget.code);
            },

            onForgetPasswordBlur () {
                let _this = this;
                return _this.forgetPasswordValidate = Pattern.validatePasswordWeak(_this.memberForget.passwordOriginal);
            },

            onForgetConfirmPasswordBlur () {
                let _this = this;
                let forgetPassword = $("#forget-confirm-password").val();
                if (Tool.isEmpty(forgetPassword)) {
                    return _this.forgetConfirmPasswordValidate = false;
                }
                return _this.forgetConfirmPasswordValidate = (forgetPassword === _this.memberForget.passwordOriginal);
            },


            /**
             * 请求重置密码
             * */
            resetPassword: function () {
                let _this = this;

                // 提交之前，先校验所有输入框
                // 注意：当有一个文本框校验为false时，其它不校验
                let mobileBlur = _this.onForgetMobileBlur();
                let mobileCodeBlur = _this.onForgetMobileCodeBlur();
                let passwordBlur = _this.onForgetPasswordBlur();
                let confirmPasswordBlur = _this.onForgetConfirmPasswordBlur();

                if (!mobileBlur && !mobileCodeBlur && !passwordBlur && !confirmPasswordBlur) {
                    return;
                }

                //code为短信验证码供后端发送短信接口使用
                //smsCode也为短信验证码供后端注册接口使用，为避免混淆使用不同属性名。
                _this.memberForget.smsCode = _this.memberForget.code;

                _this.memberForget.password = hex_md5(SALT.SALT_PREFIX + _this.memberForget.passwordOriginal + SALT.SALT_SUFFIX);

                // 调服务端密码重置接口
                _this.$ajax.post(process.env.VUE_APP_SERVER + '/business/album/member/reset-password', _this.memberForget).then((res) => {
                    let response = res.data;
                    if (response.success) {
                        Toast.success("密码重置成功");
                        _this.toLoginDiv();
                    } else {
                        Toast.warning(response.message);
                    }
                }).catch((response) => {
                    console.log("error：", response);
                })
            },

            /**
             * 发送忘记密码短信
             */
            sendSmsForForget: function () {
                let _this = this;

                if (!_this.onForgetMobileBlur()) {
                    return false;
                }

                let formDate = new FormData();
                formDate.append("mobile", _this.memberForget.mobile);

                _this.$ajax.post(process.env.VUE_APP_SERVER + '/business/album/member/check-mobile/', formDate).then((res) => {
                    let response = res.data;
                    if (response.success) {
                        _this.forgetMobileValidate = true;
                        let sms = {};
                        sms.mobile = _this.memberForget.mobile;
                        sms.use = SMS_USE.FORGET.key;
                        let date = new Date();
                        sms.millisecond = date.getTime();
                        let url = process.env.VUE_APP_SERVER + '/business/album/sms/send';
                        // 调服务端发送短信接口
                        _this.sendCode(url, sms, "forget-send-code-btn");
                    } else {
                        _this.forgetMobileValidate = false;
                        Toast.warning("手机号未注册");
                    }
                });
            },


            //-------------------------------- 注册框校验 ----------------------------

            onRegisterMobileBlur () {
                let _this = this;
                _this.registerMobileValidate = Pattern.validateMobile(_this.memberRegister.mobile);
                return _this.registerMobileValidate;
            },

            onRegisterMobileCodeBlur () {
                let _this = this;
                _this.registerMobileCodeValidate = Pattern.validateMobileCode(_this.memberRegister.code);
                return _this.registerMobileValidate;
            },

            onRegisterNameBlur () {
                let _this = this;
                _this.registerNameValidate = Pattern.validateName(_this.memberRegister.name);
                return _this.registerMobileValidate;
            },

            onRegisterPasswordBlur () {
                let _this = this;
                _this.registerPasswordValidate = Pattern.validatePasswordWeak(_this.memberRegister.passwordOriginal);
                return _this.registerMobileValidate;
            },

            onRegisterConfirmPasswordBlur () {
                let _this = this;
                let confirmPassword = $("#register-confirm-password").val();
                if (Tool.isEmpty(confirmPassword)) {
                    return _this.registerConfirmPasswordValidate = false;
                }
                return _this.registerConfirmPasswordValidate = (confirmPassword === _this.memberRegister.passwordOriginal);
            },

            //---------------------------短信验证码--------------------------

            /**
             * 倒计时
             * @param btnId
             */
            setTime(btnId) {
                let _this = this;
                let btn = $("#" + btnId);
                if (_this.countdown === 0) {
                    btn.removeAttr("disabled");
                    btn.text("获取验证码");
                    return;
                } else {
                    btn.attr("disabled", true);
                    btn.text("重新发送(" + _this.countdown + ")");
                    _this.countdown--;
                }
                setTimeout(function () {
                    _this.setTime(btnId);
                }, 1000);
            },

            /**
             * 发送短信
             * */
            sendCode: function (url, sms, btnId) {
                let _this = this;
                _this.$ajax.post(url, sms).then((response) => {
                    let responseDto = response.data;
                    if (responseDto.success) {
                        // 开始倒计时
                        _this.countdown = 60;
                        _this.setTime(btnId);
                    } else {
                        Toast.warning("操作失败")
                    }
                })
            },

            /**
             * 向后端请求短信。
             * */
            sendSmsForRegister: function () {
                let _this = this;

                if (!_this.onRegisterMobileBlur()) {
                    return false;
                }

                let formDate = new FormData();
                formDate.append("mobile", _this.memberRegister.mobile);
                _this.$ajax.post(process.env.VUE_APP_SERVER + '/business/album/member/check-mobile/',formDate).then((res) => {
                    let response = res.data;
                    if (response.success) {
                        Toast.warning("手机号已被注册");
                    } else {
                        let sms = {};
                        sms.mobile = _this.memberRegister.mobile;
                        sms.use = SMS_USE.REGISTER.key;
                        let date = new Date();
                        sms.millisecond = date.getTime();
                        let url = process.env.VUE_APP_SERVER + '/business/album/sms/send';
                        // 调服务端发送短信接口
                        _this.sendCode(url, sms, "register-send-code-btn");
                    }
                });

            },

            //-------------------记住我---------------------------
            /**
             * 记住我
             * */
            rememberMember: function () {
                let _this = this;
                //用户登录时是否记住登录的用户信息
                let rememberUser = LocalStorage.get(LOCAL_KEY_REMEMBER_USER);
                if (rememberUser) {
                    _this.member = rememberUser;
                }
            },

            //-------------------登录---------------------------

            /**
             * 会员登录
             * */
            loginMember: function () {
                let _this = this;
                //记住我
                /**
                 * 记住我的实现思路
                 * 将用户信息存入本地缓存时增加一个属性md5Mark作为标记用于比较和密码框中的密码是否一样，
                 * md5Mark属性的值是由：被第一次加密后，再次加密得到。
                 * 提示：其实密码框中的密码是被第一次加密的值
                 * 准备一个从登录密码框获取的密码并经过md5加密的值hexMd5
                 * 在用户登录前判断：
                 * 如果hexMd5和md5Mark是一样的，说明用户上次成功登录过，
                 * 那就直接把密码框中的密码不再加密直接发送到后端登录即可。
                 * 如果hexMd5和md5Mark是不一样的，说明用户上次并没有成功登录，或者根本就是另一个用户，
                 * 他已经将密码框中的密码重新填入并点击了登录，
                 * 那就将用户的密码前后都加上盐值经过md5加密后发送到后端验证登录即可。
                 * */
                let hexMd5 = hex_md5(_this.member.password);
                let localCacheUser = LocalStorage.get(LOCAL_KEY_REMEMBER_USER);
                if (localCacheUser == null || hexMd5 !== localCacheUser.md5Mark) {
                    //前后都加上一个盐值，md5加密一次
                    _this.member.password = hex_md5(SALT.SALT_PREFIX + _this.member.password + SALT.SALT_SUFFIX);
                }

                _this.member.imageCodeToken = _this.imageCodeToken;

                _this.$ajax.post(process.env.VUE_APP_SERVER + '/business/album/member/login', _this.member).then((response)=>{
                    let resp = response.data;
                    if (resp.success) {
                        //是否记住登录用户
                        if (_this.rememberMe) {
                            //将加密过后的password再用md5再加密一次，得到一个新的md5值作为标记
                            let md5Mark = hex_md5(_this.member.password);
                            //将登录名和密码作为value值写入到本地缓存KEY当中
                            LocalStorage.set(LOCAL_KEY_REMEMBER_USER, {
                                mobile: _this.member.mobile,
                                password: _this.member.password,
                                md5Mark: md5Mark,
                            });
                        } else {
                            //否，将本地缓存KEY的value值清空
                            LocalStorage.remove(LOCAL_KEY_REMEMBER_USER);
                            //或者直接赋值为null也可以
                            //LocalStorage.set(LOCAL_KEY_REMEMBER_USER,null);
                        }
                        // console.log("登录成功 = " + JSON.stringify(resp.content));

                        // 登录成功后，调用父组件的setLoginMember函数获取登录后的用户信息
                        _this.$parent.setLoginMember(resp.content);
                        $("#login-modal").modal("hide");
                    } else {
                        _this.member.password = null;
                        _this.member.imageCode = null;
                        _this.loadImageCode();
                        Toast.error(resp.message);
                    }
                })
            },

            //---------------登录框、注册框、忘记密码框切换-----------------
            toLoginDiv() {
                let _this = this;
                _this.MODAL_STATUS = _this.STATUS_LOGIN
            },
            toRegisterDiv() {
                let _this = this;
                _this.MODAL_STATUS = _this.STATUS_REGISTER
            },
            toForgetDiv() {
                let _this = this;
                _this.MODAL_STATUS = _this.STATUS_FORGET
            },

            /**
             * 打开登录注册窗口
             */
            openLoginModal() {
                let _this = this;
                // 显示登录框时就刷新一次验证码图片
                _this.loadImageCode();
                _this.registerMobileValidate = null;
                _this.registerMobileCodeValidate = null;
                _this.registerPasswordValidate = null;
                _this.registerNameValidate = null;
                _this.registerConfirmPasswordValidate = null;
                $("#login-modal").modal("show");
                _this.toLoginDiv();
            },

            //------------------注册会员-----------------------------
            register() {
                let _this = this;

                // 提交之前，先校验所有输入框
                // 注意：所有文本框校验为true时，才通过
                let mobileBlur = _this.onRegisterMobileBlur();
                let codeBlur = _this.onRegisterMobileCodeBlur();
                let nameBlur = _this.onRegisterNameBlur();
                let passwordBlur = _this.onRegisterPasswordBlur();
                let confirmPasswordBlur = _this.onRegisterConfirmPasswordBlur();
                if (!mobileBlur&&!codeBlur&&!nameBlur&&!passwordBlur&&!confirmPasswordBlur) {
                    return;
                }

                //code为短信验证码供后端发送短信接口使用
                //smsCode也为短信验证码供后端注册接口使用，为避免混淆使用不同属性名。
                _this.memberRegister.smsCode = _this.memberRegister.code;

                _this.memberRegister.password = hex_md5(SALT.SALT_PREFIX + _this.memberRegister.passwordOriginal + SALT.SALT_SUFFIX);

                // 调服务端注册接口
                _this.$ajax.post(process.env.VUE_APP_SERVER + '/business/album/member/register', _this.memberRegister).then((response) => {
                    let resp = response.data;
                    if (resp.success) {
                        Toast.success("注册成功");
                        _this.toLoginDiv();
                    } else {
                        Toast.warning(resp.message);
                    }
                })
            },

            //---------------登录框-----------------
            /**
             * 加载图形验证码
             */
            loadImageCode: function () {
                let _this = this;
                _this.imageCodeToken = Tool.uuid(8);
                $('#image-code').attr('src', process.env.VUE_APP_SERVER + '/business/album/kaptcha/image-code/' + _this.imageCodeToken);
            },

        }
    }
</script>

<style scoped>
    /* 登录框 */
    .login-div .input-group-addon {
        padding: 0;
        border: 0;
        width: 34.5%;
    }

    #image-code{
        height: 100%;
    }

    #image-code-input{
        max-width: 65.5%;
    }

    #login-modal h3 {
        text-align: center;
        margin-bottom: 20px;
    }

    #login-modal .modal-login {
        max-width: 400px;
    }

    #login-modal input:not(.rememberMe) {
        height: 45px;
        font-size: 16px;
    }

    #login-modal .submit-button {
        height: 50px;
        font-size: 20px;
    }

    #login-modal .to-login-div {
        text-align: center;
    }
</style>
